home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
OOPTUT34.ZIP
/
TVISION.TXT
< prev
next >
Wrap
Text File
|
1993-06-12
|
22KB
|
444 lines
TURBO VISION.
-------------
Introduction.
-------------
Since Turbo Vision makes use of object-oriented techniques, including
inheritance and polymorphism, it is necessary to be completely familiar
with object-oriented programming. Furthermore the object instances are
dynamically allocated on the heap, so that familiarity with pointers and
dynamic variables is also essential. The extended syntax of the 'New'
procedure, which allows the allocation of space on the heap for an object
and its initialization within the one procedure must also be appreciated.
This new procedure is now invoked with two parameters, the pointer name as
the first parameter and the constructor invocation as the second parameter.
All these topics are covered in the notes on Advanced Data Structures and
Object-Oriented Programming.
In OOP parlance, an 'object type' is an abstraction that provides a
template for specific objects, which are themselves called 'instances' of
that object type. In Turbo Vision, the templates or object types all start
with the letter T, whilst all pointer types start with the letter P. Both
the object instances and the actual pointer variables have names
appropriate to the circumstances of use. Thus typical variable
declarations are:
VAR
Window: PDemoWindow; {see page 32 of the Turbo Vision Guide}
R: TRect;
The extended syntax of 'New' also allows it to be used as a function,
returning a pointer value. An example taken from page 32 of the Guide is:
Window := New(PDemoWindow, Init( R, 'Demo Window',WinCount));
| | / \ | |
Pointer Pointer Constructor Object Title Number
variable type invocation of type
TRect
Thus Window is a pointer of type PDemoWindow, which itself has been
previously declared as:
TYPE
PDemoWindow = ^TDemoWindow; { a pointer to type TDemoWindow }
TDemoWindow = OBJECT(TWindow) { a simple user-defined descendant }
END; { object of TWindow }
Hence Window points to an object type TDemoWindow, which inherits the
fields and methods from the ancestor object type TWindow (see pages
321-325). The 'Init' method for TWindow is a static method and is defined
on page 322. Three parameters are required, namely the bounds, a title and
a number.
The bounds are given by the parameter R, which is of type TRect (see page
278), whose data fields define the corners at the top left (A) and the
bottom right (B) of the rectangle. One of TRect's (static) methods is the
Assign procedure, which gives the coordinates to the points A and B as XA,
YA, XB, YB (each of type integer).
The assignment is made using the conventional dot notation, so as on page
32 the statement is:
R.Assign(0, 0, 26, 7); { set initial size and position }
The second parameter to a TWindow initialization is a literal title (in
single quotes) and this will be displayed at the top of the window, along
with the third parameter, the WinCount number.
The declarations and assignments shown in the above few paragraphs
illustrate the existence in Turbo Vision of predefined objects, each with
its appropriate fields and methods, some of which are static and may be
used directly, whilst others are virtual and may be overridden.
The way in which objects inherit from ancestor types is indicated in the
Turbo Vision object hierarchy shown on page 66 of the Turbo Vision Guide.
It is seen that the object type TWindow referred to in the preceding
paragraphs is part of this hierarchy tree:
TObject --- TView -----
| |--
| |--
| |--
| |-- TGroup -----
|--
|-- TWindow -----
|--
Each of these object types is sufficiently defined for any user application
in Chapter 13 'Object reference' on pages 205-325. The actual code is only
accessible as a compiled unit (.TPU file), the name of which is also shown
in the reference. Thus the 'root' ancestor TObject (pages 267-8) is shown
to be part of OBJECTS.TPU, to have no fields and just three methods, Init,
Free (both static) and Done (virtual).
Apart from TPoint and TRect (see below) all Turbo Vision's standard objects
are ultimately derived from TObject. Any object that uses Turbo Vision's
streams facilities must trace its ancestry back to TObject.
TView is found in VIEWS.TPU, it has 11 fields, including size and options,
and 64 methods, including Init, Done, Draw, Show and WriteLine (pages
306-321).
TGroup is also in VIEWS.TPU, it has 4 fields and 29 methods (pages
235-244).
Because units are used, it follows that there must be a USES statement at
the start of any application program to ensure that all the required TPUs
are called. Chapter 12 'Unit cross reference' (pages 189-204) gives
details of all the units used by Turbo Vision. Types, constants,
variables, procedures and functions are listed for each unit.
Because of inheritance, it is possible that a method used by any object
type may not be its own, but that of an ancestor type. It may therefore be
necessary to refer back through the hierarchy to find the definition of a
particular method.
TPoint is a simple object type representing a point on the screen by its
only two fields X and Y. It has no methods and is thus only a record and is
the ultimate abstraction as far as screen display is concerned.
TRect has two fields, A and B, both of type TPoint and 9 methods.
Apart from the standard object hierarchy of Turbo Vision, there are a
number of other elements (types, constants, variables, procedures and
functions) which are defined in the Turbo Vision units. These are listed
in Chapter 14, 'Global reference' on pages 327-384 and include for example:
TYPE PString defines a pointer to a string OBJECTS.TPU
PtrRec record of ofs & seg of a pointer OBJECTS.TPU
CONSTANT hcXXXX help context constants VIEWS.TPU
ofXXXX options flags VIEWS.TPU
VARIABLE ScreenHeight height in lines of current screen DRIVERS.TPU
MenuBar stores a pointer to menu bar APP.TPU
PROCEDURE DisposeMenu disposes all elements of the menu OBJECTS.TPU
ClearScreen clears the screen DRIVERS.TPU
FUNCTION NewStatusDef returns a pointer to a new
TStatusDef record MENUS.TPU
Turbo Vision examples.
----------------------
Now that the structure of Turbo Vision and the notation has been
presented, it is possible to proceed with discussion of a specific example,
which relates to a screen display like that of the Turbo Pascal Integrated
Development Environment. The display has a working area called the
Desktop, which occupies most of the screen, a Menu Bar at the top and a
Status Line at the bottom, which provides the user with advice on how to
proceed, even if it is only - Alt-X Exit.
The example is described in detail in Chapter 2 of the Turbo Vision Guide
(pages 23- 28). The program is in TVGUID01.PAS which is included with the
demo programs on the distribution disks and is listed below:
PROGRAM TFirst;
USES App; { application objects are in APP.TPU }
TYPE TMyApp = OBJECT(TApplication) { define new application type leaving }
END; { room for future expansion }
VAR MyApp : TMyApp; { create an instance of the new type }
BEGIN
MyApp.Init { set it up }
MyApp.Run { interact with the user }
MyApp.Done { clean up afterwards }
END.
At present the new object type TMyApp is no different to TApplication, but
it will be in due course when the methods of TApplication are overridden.
The default behaviour of a TApplication produces a simple screen with a
blank menu bar, an empty desktop and a status line with only 'Alt-X Exit'.
These screen areas have been created by the TApplication (virtual) methods
InitDeskTop, InitMenuBar and InitStatusLine, which are inherited from
TProgram, the ancestor type to TApplication (see page 272). Whereas the
DeskTop initialization is seldom overridden, the other two are always
overridden in any meaningful application.
The object type TApplication is a simple 'wrapper' around TProgram and only
differs from TProgram in its constructor and destructor methods.
TApplication.Init first initializes all Turbo Visions subsystems (the
memory, video, event, system error and history list managers) and then
calls TProgram.Init. Likewise, TApplication.Done first calls TProgram.Done
and then shuts down all Turbo Vision subsystems.
Thus the new descendant type TMyApp has an Init method, MyApp.Init, which
will call the inherited TApplication.Init and then call the initialization
code specific to the new application, overriding some of the inherited
virtual methods. An example of a new virtual method is illustrated in
TVGUID02.PAS, which has a procedure InitStatusLine; virtual; added to the
type declaration of TMyApp.
This new initialization procedure (shown on the next page) involves a
sequence of nested calls to standard Turbo Vision functions NewStatusDef
and NewStatusKey. The return values to these functions are PStatusDef,
which points to a type TStatusDef, and PStatusItem, which points to a type
TStatusItem, respectively.
The TStatusDef type represents a status line definition and is a record
type declared in MENUS.TPU as follows:
TStatusDef = RECORD
Next : PStatusDef; {points to next TStatusDef in a list or NIL}
Min, Max : Word; {define range of help contexts for status line}
Items : PStatusItem; {points to a list of status line items or NIL}
END;
The TStatusItem type represents a status line item that can be visible or
invisible and is a record type declared in MENUS.TPU as follows:
TStatusItem = RECORD
Next : PStatusItem; {points to next TStatusItem in a list or NIL}
Text : PString; {points to string containing status item legend}
{such as 'Alt-X Exit' or NIL if item invisible }
KeyCode : Word; {contains scan code of hot key for item or zero}
Command : Word; {contains command event generated when selected}
END;
The linked lists involved in the above two record types were described in
the notes on Advanced Data Structures, to which reference should be made
if necessary (HEAP&PTR.TXT on the Turbo Pascal Tutor diskette).
The NewStatusDef function (page 360) allocates and returns a pointer to a
new TStatusDef record. The function declaration is:
FUNCTION NewStatusDef(AMin, AMax: Word; AItems: PStatusItem; ANext:
PStatusDef): PStatusDef;
The record is initialized with the given parameter values. Calls to
NewStatusDef and NewStatusKey can be nested to create entire status line
definitions in one Pascal statement as shown in the example below.
The NewStatusKey function (page 360) allocates and returns a pointer to a
new TStatusItem record. The function declaration is:
FUNCTION NewStatusKey(AText: String; AKeyCode: Word; ACommand: Word;
ANext: PStatusItem): PStatusItem;
The record is initialized with the given parameter values. If AText is
empty, the status item is hidden, but will still provide a mapping from the
given KeyCode to the given Command.
The important statement in the InitStatusLine procedure involves the
StatusLine variable of type PStatusLine (page 372) which stores a pointer
to the application's status line. TStatusLine is an object type defined in
MENUS.TPU and described on pages 292-294. It is initialized as follows:
CONSTRUCTOR Init(var Bounds: TRect; ADefs: PStatusDef);
Thus using the extended form of the New function with the constructor
invocation as the second parameter, the form of the statement is
StatusLine := New(PStatusLine, Init(VAR Bounds: TRect; ADefs: PStatusDef);
where the Bounds of type TRect is simply R and ADefs of type PStatusDef is
obtained as the value returned by the function NewStatusDef (see above),
whilst the third parameter of this function AItems of type PStatusItem is
obtained as the value returned by the function NewStatusKey (see above).
In this case the fourth parameter of the function NewStatusKey which is
ANext of type PStatusItem can itself be obtained as the value returned by
another call to the function NewStatusKey and so on if necessary until a
pointer value of NIL is encountered.
Thus the complete InitStatusLine procedure becomes:
PROCEDURE TMyApp.InitStatusLine;
VAR R: TRect; {holds the boundaries of status line}
BEGIN
GetExtent(R); {set R to coordinates of full screen}
R.A.Y := R.B.Y - 1; {move top to one line above bottom}
StatusLine := New(PStatusLine, Init(R, {create status line}
NewStatusDef(0, $FFFF, {set range of help contexts}
NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, {define item}
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose, {another}
nil)), {no more keys}
nil) {no more defs}
)); {bracket closures for Init and New}
END;
It is also necessary to add PROCEDURE InitStatusLine; VIRTUAL; to the
declaration of TMyApp.
The initialization is a sequence of nested calls to standard Turbo Vision
functions NewStatusDef and NewStatusKey. The program defines a status line
for a range of help contexts from 0 to $FFFF and binds the standard Turbo
Vision command cmQuit to the Alt-X keystroke and the standard command
cmClose to the Alt-F3 key.
There is no need for the InitStatusLine method to call the method it
overrides, TApplication.InitStatusLine, as there is nothing in the
overridden method that would help.
The part of the string 'Alt-F3 Close' enclosed within the tildes(~) will be
highlighted on the screen, once a window has been opened and will allow a
mouse-click activation. If no window is open then it is not highlighted
and the cmClose command is disabled by default.
The commands cmQuit and cmClose are standard Turbo Vision commands and do
not require the user to define them. Customized commands are declared as
constant values, in the ranges 100-255 (disable) and 1000-65535
(non-disable). Thus the following lines can be added to the above program:
CONST
cmNewWin = 199;
.....
.....
NewStatusKey('~F4~ New', kbF4, cmNewWin, { bind new command}
.....
) { close bracket after first NIL}
The Menu Bar is slightly more complicated than the Status Line, because of
the pull-down sub-menus, but is similarly initialized with nested calls to
the standard Turbo Vision functions NewMenu, NewSubMenu, NewItem and
NewLine.
The MenuBar variable (page 355) stores a pointer (of type PMenuView) to the
application's menu bar (of type TMenuBar), a descendant of TMenuView. It
is defined in MENUS.TPU and is initialized as follows:
CONSTRUCTOR Init(VAR Bounds: TRect; AMenu: PMenu);
Thus using the extended form of the New function with the constructor
invocation as the second parameter, the form of the statement is:
MenuBar := New(PMenuBar, Init(VAR Bounds: TRect; AMenu: PMenu);
where the bounds of type TRect is again R and in this case AMenu, of type
PMenu, is obtained as the value returned by the function NewMenu (page
359), which requires a parameter 'Items' of type PMenuItem. This parameter
of type PMenuItem is itself returned by the function 'NewSubMenu' (page
361), which requires as its parameters:
Name: TMenuStr; { a defined string type of 31 characters - p 378}
AHelpCtx: Word; { a help context constant }
SubMenu: PMenu; { value returned by function NewMenu - p 359 }
Next; PMenuItem; { value returned by function NewItem - p 359 }
The function NewItem is declared as follows:
FUNCTION NewItem(Name, Param: TMenuStr; KeyCode: Word: Command: Word;
AHelpCtx: Word; Next: PMenuItem): PMenuItem;
from which it is clear that NewItem may call itself for the last parameter.
The nested structure of these various function calls can be illustrated as
follows:
MenuBar allocation and initialization requires the parameter PMenu from the
function NewMenu and
Function Parameter obtained from Return value
------------------------------------------------------------------
NewMenu 1 - PMenuItem NewSubMenu PMenu
NewSubMenu 3 - PMenu NewMenu PMenuItem
4 - PMenuItem NewSubMenu (another)
NewItem 5 - PMenuItem NewItem (another) PMenuItem
Applications to show windows in the desktop area of the screen are
illustrated in the demonstration programs TVGUID04.PAS to TVGUID10.PAS, but
contain only a few new concepts. Apart from Event Handling to be discussed
later, the following new objects and statements are introduced:
A TWindow object which is a specialized group that typically owns a TFrame
object, an interior TScroller object and one or two TScrollBar objects.
These attached subviews provide the "visibility" to the TWindow object.
The TFrame object provides the border, a place for an optional title and
number and functional icons (close, zoom, drag). TWindow objects have the
"built-in" capability of moving and growing via mouse drag or cursor
keystrokes. They can be zoomed and closed via mouse clicks in the
appropriate icon regions. They work with scroll bars and scrollers.
Numbered windows can be selected with ALT-n keys (n = 1 to 9). TWindow
initialization requires three parameters: Bounds of type TRect, a title of
type TTitleStr and a window number.
TDeskTop is a descendant of TGroup and inherits the procedure Insert, which
requires a parameter of type PView. Thus the statement to place a window
in the desktop is: DeskTop^.Insert(Window) where Window is a pointer
Any number of views, called subviews, can be inserted into a group object
like desktop, which is called the owner view.
To place something into a window, a view called an interior is created and
then inserted. An object TInterior, a descendant of TView, with its own
initialization constructor and own draw procedure is introduced. The
WriteStr procedure, inherited from TView, is added to the TInterior.Draw
procedure. The TInterior initialization includes the GrowMode variable,
which ensures that the subview will grow as the owner view is resized.
TVGUID05.PAS displays a Demo Window, with "Hello World" inserted.
Frequently it will be necessary to create a procedure 'ReadFile' to read a
file for insertion in a window. The normal assign and reset statements are
followed by a while loop to read each line and dynamically allocate heap
storage, returning a pointer to the first byte of each string, using the
NewStr function. This is illustrated in the program TVGUID06.PAS and shown
on page 39 of the Turbo Vision Guide.
Another procedure 'TInterior.Draw' then uses the standard procedure
MoveChar (page 358) to move spaces into a buffer, prior to using another
standard procedure MoveStr (page 358) to move a string into the buffer and
then uses the WriteLine procedure, inherited from TView, to write the line
contained in the buffer to the screen (page 321). This procedure is used
in TVGUID07.PAS and is shown on page 40 of the Guide.
In order to see the whole file on the screen is necessary to be able to
scroll up and down, with the mouse reacting with scroll bars at the right
and bottom of the view. In this case the object type TInterior is a
descendant of TScroller, instead of TView, as above. The new constructor
invocation has a bounds parameter and also two pointers of type PScrollBar,
namely HScrollBar and VScrollBar, which point to the horizontal and
vertical scroll bars respectively.
A procedure TDemoWindow.MakeInterior uses the function 'StandardScrollBar',
inherited from type TWindow, to create, inset and return a pointer to a
standard scroll bar for the window. The constructor invocation for
TScroller uses the parameters Bounds, HScrollBar and VScrollBar and is
called within the New function in order to obtain the pointer to the
'Interior'. Finally the insert procedure, inherited from TGroup, is called
to insert the interior.
TVGUID08.PAS provides an illustration of a scrolling interior and is shown
in part on pages 42-44 of the Guide.
Finally, a program provided on Borland's Install diskette, TVDEMO.PAS, can
be modified by the user for his own purposes, using the above information
to create a menu-bar, desk-top and status-line display for any number of
text files, including source code, etc. The writer of these notes has made
use of this program for this tutorial display.
TVISION.TXT
20.3.91
Revised 12.6.93